iT邦幫忙

2022 iThome 鐵人賽

DAY 29
0
自我挑戰組

I don't know JS yet系列 第 29

[ Day 29 ] I don't know JS yet - Variable re-declaration ? ( part 2 )

  • 分享至 

  • xImage
  •  

今天延續昨天份的學習
在迴圈裡宣告的變數,算不算 re-declare ?

先公佈答案:不算。

範例一:在 while() 裡宣告 let 變數,算 re-declare 嗎?

var keepGoing = true;
while(keepGoing) {
    let value = Math.random();
    if (value > 0.5) {
        keepGoing = false;
    }
}

value 被 re-declare 了嗎? 沒有。
為什麼?
每跑一次迴圈,就是產生宣告新的 value 變數,所以第一次與第二次 per scope instance 不會一樣,因此不是 "re-declare" 。

假如將 let 換成 const 也不會有 Error,因為每跑一次迴圈,就會產生獨一無二的 per scope instance,不是 "re-declare"。

還有,let, const變數本身就不能做 re-declare 了,如果上面的 snippet 是 re-declare 的話,會跳 Syntax Error 才對。

範例二:在 while() 裡宣告 var 變數,算 re-declare 嗎?

var keepGoing = true;
while (keepGoing) {
    var value = Math.random();
    if (value > 0.5) {
        keepGoing = false;
    }
}

value 被 re-declare 了嗎? 沒有。
為什麼? var 變數不是可以 re-declare 嗎?
回想 var 變數的作用域,是 functional scope,不是 block scope。
因此第三行的 value 宣告,會被提升到 while() 的外層( globle scope ),與 keepGoing 在同個 scope。而迴圈裡的 var value = Math.random() 可以想成 value = Math.random(),只是在做 re-assignment 而已。

範例三:for(...) initialExpression 算 re-declare 嗎?

for (let i = 0; i < 3; i++) {
    let value = i * 10;
    console.log(`${ i }: ${ value }`);
}
// 0: 0
// 1: 10
// 2: 20

let i = 0 看起來每跑一次迴圈,就會重新宣告一次對吧?
那麼 i 真的 re-declare 了嗎? 沒有。
為什麼?
真正發生的情況是這樣的:

{
    // a fictional variable for illustration
    let $$i = 0;

    for ( /* nothing */; $$i < 3; $$i++) {
        // here's our actual loop `i`!
        let i = $$i;

        let value = i * 10;
        console.log(`${ i }: ${ value }`);
    }
    // 0: 0
    // 1: 10
    // 2: 20
}

i 變數的 scope 是在 for(...){} 裡面,不是外面
每跑一次迴圈,會產生新的 ivalue per scope instance,所以不會 "re-declare"。

範例四:for(...) initialExpression 用 const 宣告變數?

for (const i = 0; i < 3; i++) {
    // oops, this is going to fail with
    // a Type Error after the first iteration
}

Type Error,但是在哪發生的 ... ?
我們將上面的 snippet 拆解其作用域

{
    const $$i = 0;
    
    for ( ; $$i < 3; $$i++) {
        const i = $$i;
    }
    
}

找到了嗎?在 incrementExpresstion $$i++ $$i 被 re-assignment 了。
所以通常在 for() 迴圈,initialExpression 會使用 var 或者 let 來宣告變數。

今天份的學習到這邊


上一篇
[ Day 28 ] I don't know JS yet - Variable Re-declaration? ( part1 )
下一篇
[ Day 30 ] I don't know JS yet
系列文
I don't know JS yet30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言